import {
  _decorator,
  Node,
  Camera,
  RenderTexture,
  ImageAsset,
  view,
  Texture2D,
  SpriteFrame,
  Sprite,
  native,
  UITransform,
  sys,
  log,
  error,
  assetManager,
  instantiate,
  v3,
  Component,
  EventTouch,
} from 'cc';
import { Canvas2Image } from './Canvas2Image';
import { Screenshot2DModel_Ins } from './Screenshot2DModel';

const { ccclass, property } = _decorator;

@ccclass('Screenshot2D')
export class Screenshot2D extends Component {
  @property(Camera)
  copyCamera: Camera = null!;
  // @property(Label)
  // scoreLab: Label = null!;

  @property(Node)
  targetNode: Node = null!;

  // @property(Button)
  // downloaderBtn: Button = null!;
  // @property(Button)
  // shareBtn: Button = null!;

  @property(Node)
  copyMask: Node = null!;
  @property(Node)
  copyNode: Node = null!;
  // @property(Node)
  // bgNode: Node = null!;
  // @property(Node)
  // uxNode: Node = null!;

  // @property(Node)
  downloadNode: Node = null!;

  // @property(Label)
  // tips: Label = null!;

  rt: RenderTexture = null;

  _canvas: HTMLCanvasElement = null!;

  _buffer: Uint8Array = null!;

  canvas2image: Canvas2Image = null!;

  score: string;

  curSpr: SpriteFrame = null;

  constructor() {
    super();
  }

  protected onLoad(): void {
    Screenshot2DModel_Ins.panel = this;
  }

  protected onEnable(): void {
    // this.initData();
    // this.copyMask.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
    const uitrans = this.copyNode.getComponent(UITransform);
    const viewSize = view.getVisibleSize();
    uitrans.width = viewSize.width;
    uitrans.height = viewSize.height;
  }

  onTouchStart(t: EventTouch) {
    this.copyMask.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    this.copyMask.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
    const pos = this.node.getComponent(UITransform).convertToNodeSpaceAR(v3(t.getUILocation().x, t.getUILocation().y, 0));
    this.copyMask.setPosition(pos);
  }

  onTouchMove(t: EventTouch) {
    const pos = this.node.getComponent(UITransform).convertToNodeSpaceAR(v3(t.getUILocation().x, t.getUILocation().y, 0));
    this.copyMask.setPosition(pos);
  }

  onTouchEnd(t: EventTouch) {
    this.copyMask.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
    this.copyMask.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
  }

  /** 截图 */
  capture() {
    this.initData();
    setTimeout(() => {
      this.copyRenderTex();
    }, 1);
  }

  initData() {
    this.canvas2image = Canvas2Image.getInstance();
    this.copyCamera.node.active = true;
    this.rt = new RenderTexture();
    this.rt.reset({
      width: view.getVisibleSize().width,
      height: view.getVisibleSize().height,
    });
    this.copyCamera.targetTexture = this.rt;
  }

  copyRenderTex() {
    const width = this.targetNode.getComponent(UITransform).width;
    // const height = this.targetNode.getComponent(UITransform).height;
    // const worldPos = this.targetNode.getWorldPosition();
    const viewSize = view.getVisibleSize();
    console.log(viewSize.width, viewSize.height);

    // this._buffer = this.rt.readPixels(0, 0, viewSize.width, viewSize.height);
    this._buffer = this.rt.readPixels(0, 0, viewSize.width, viewSize.height);
    this.showImage(width, viewSize.height);
    this.copyCamera.node.active = false;
  }

  showImage(width: number, height: number) {
    const img = new ImageAsset();
    img.reset({
      _data: this._buffer,
      width: width,
      height: height,
      format: Texture2D.PixelFormat.RGBA8888,
      _compressed: false,
    });
    const texture = new Texture2D();
    texture.image = img;
    const sf = new SpriteFrame();
    sf.texture = texture;
    sf.packable = false;
    this.copyNode!.getComponent(Sprite).spriteFrame = sf;
    this.copyNode!.getComponent(Sprite).spriteFrame.flipUVY = true;
    if (sys.isNative && (sys.os === sys.OS.IOS || sys.os === sys.OS.OSX)) {
      this.copyNode!.getComponent(Sprite).spriteFrame.flipUVY = false;
    }
    this.curSpr = sf;
    this.copyCamera.targetTexture = null;
    // this.copyNode?.getComponent(UITransform)?.setContentSize(new Size(416, 863));
    // this.downloaderBtn.node.active = false;
    // this.shareBtn.node.active = false;

    // this.tips.string = `截图成功`;
    // console.log(`截图成功`);
  }

  savaAsImage(width: number, height: number, arrayBuffer: Uint8Array) {
    if (sys.isBrowser) {
      /** 浏览器 */
      if (!this._canvas) {
        this._canvas = document.createElement('canvas');
        this._canvas.width = width;
        this._canvas.height = height;
      } else {
        this.clearCanvas();
      }
      const ctx = this._canvas.getContext('2d')!;
      /** 每4个数据 代表一个像素 */
      const rowBytes = Math.floor(width * 4);
      for (let row = 0; row < height; row++) {
        const sRow = Math.floor(height - 1 - row);
        const imageData = ctx.createImageData(width, 1);
        const start = sRow * rowBytes;
        for (let i = 0; i < rowBytes; i++) {
          imageData.data[i] = arrayBuffer[start + i];
        }
        ctx.putImageData(imageData, 0, row);
        // ctx.putImageData;
      }
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      this.canvas2image.saveAsPNG(this._canvas, width, height);
      // this.tips.string = `保存图片成功`;
      // console.log(`保存图片成功`);
    } else if (sys.isNative) {
      /** 安卓 */
      const filePath = native.fileUtils.getWritablePath() + 'render_to_sprite_image.png';
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      //@ts-ignore
      if (native.saveImageData) {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        //@ts-ignore
        native
          .saveImageData(this._buffer, width, height, filePath)
          .then(() => {
            assetManager.loadRemote<ImageAsset>(filePath, (err, imageAsset) => {
              if (err) {
                console.log('show image error');
              } else {
                const newNode = instantiate(this.targetNode);
                newNode.setPosition(v3(-newNode.position.x, newNode.position.y, newNode.position.z));
                this.targetNode.parent.addChild(newNode);

                const spriteFrame = new SpriteFrame();
                const texture = new Texture2D();
                texture.image = imageAsset;
                spriteFrame.texture = texture;
                newNode.getComponent(Sprite).spriteFrame = spriteFrame;
                spriteFrame.packable = false;
                spriteFrame.flipUVY = true;
                if (sys.isNative && (sys.os === sys.OS.IOS || sys.os === sys.OS.OSX)) {
                  spriteFrame.flipUVY = false;
                }
                // this.tips.string = `成功保存在设备目录并加载成功: ${filePath}`;
                // console.log(`成功保存在设备目录并加载成功: ${filePath}`);
              }
            });
            log('save image data success, file: ' + filePath);
            // this.tips.string = `成功保存在设备目录: ${filePath}`;
            // console.log(`成功保存在设备目录: ${filePath}`);
          })
          .catch(() => {
            error('save image data failed!');
            // this.tips.string = `保存图片失败`;
            // console.log(`保存图片失败`);
          });
      }
    } else if (sys.platform === sys.Platform.WECHAT_GAME) {
      /** 微信 */
      if (!this._canvas) {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        //@ts-ignore
        this._canvas = wx.createCanvas();
        this._canvas.width = width;
        this._canvas.height = height;
      } else {
        this.clearCanvas();
      }
      const ctx = this._canvas.getContext('2d');

      const rowBytes = Math.floor(width * 4);

      for (let row = 0; row < height; row++) {
        const sRow = height - 1 - row;
        const imageData = ctx.createImageData(width, 1);
        const start = sRow * width * 4;

        for (let i = 0; i < rowBytes; i++) {
          imageData.data[i] = arrayBuffer[start + i];
        }

        ctx.putImageData(imageData, 0, row);
      }
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      //@ts-ignore
      this._canvas.toTempFilePath({
        x: 0,
        y: 0,
        width: this._canvas.width,
        height: this._canvas.height,
        destWidth: this._canvas.width,
        destHeight: this._canvas.height,
        fileType: 'png',
        success: (res) => {
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          //@ts-ignore
          wx.showToast({
            title: '截图成功',
          });
          // this.tips.string = `截图成功`;
          // console.log(`截图成功`);
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          //@ts-ignore
          wx.saveImageToPhotosAlbum({
            filePath: res.tempFilePath,
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            success: (res) => {
              // eslint-disable-next-line @typescript-eslint/ban-ts-comment
              //@ts-ignore
              wx.showToast({
                title: '成功保存到设备相册',
              });
              // this.tips.string = `成功保存在设备目录: ${res.tempFilePath}`;
              // console.log(`成功保存在设备目录: ${res.tempFilePath}`);
            },
            fail: () => {
              // this.tips.string = `保存图片失败`;
              // console.log(`保存图片失败`);
            },
          });
        },
        fail: () => {
          // eslint-disable-next-line @typescript-eslint/ban-ts-comment
          //@ts-ignore
          wx.showToast({
            title: '截图失败',
          });
          // this.tips.string = `截图失败`;
          // console.log(`截图失败`);
        },
      });
    }
  }

  clearCanvas() {
    const ctx = this._canvas.getContext('2d');
    ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
  }

  onSaveImageBtnClicked() {
    const nodeTs = this.downloadNode.getComponent(UITransform);
    const wordPos = this.downloadNode.getWorldPosition();

    const width = nodeTs.width;
    const height = nodeTs.height;

    const rt = new RenderTexture();
    rt.reset({
      width: width,
      height: width,
    });
    this.copyCamera.targetTexture = this.rt;
    const buffer = this.rt.readPixels(wordPos.x - width / 2, wordPos.y - height / 2, width, height);
    this.savaAsImage(width, height, buffer);
    // this.downloaderBtn.node.active = false;
  }

  onShareBtnClick() {
    // 分享好友
    // AudioManager.I.playSound(AudioManager.I.getClick2Code());
    // this.shareBtn.node.active = false;

    const nodeTs = this.downloadNode.getComponent(UITransform);
    const wordPos = this.downloadNode.getWorldPosition();
    const width = nodeTs.width;
    const height = nodeTs.height;
    const buffer = this.rt.readPixels(wordPos.x - width / 2, wordPos.y - height / 2, width, height);
    if (!this._canvas) {
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      //@ts-ignore
      this._canvas = wx.createCanvas();
      this._canvas.width = width;
      this._canvas.height = height;
    } else {
      this.clearCanvas();
    }
    const ctx = this._canvas.getContext('2d');

    const rowBytes = Math.floor(width * 4);

    for (let row = 0; row < height; row++) {
      const sRow = height - 1 - row;
      const imageData = ctx.createImageData(width, 1);
      const start = sRow * width * 4;

      for (let i = 0; i < rowBytes; i++) {
        imageData.data[i] = buffer[start + i];
      }
      ctx.putImageData(imageData, 0, row);
    }
    // MultiPlatform.Ins.platformJs.shareToFriend(this._canvas);
  }

  onClickClose() {
    // AudioManager.I.playSound(AudioManager.I.getClick2Code());
    // FrameManager.I.hideFrame(FrameType.ScreenshotFrame);
  }
}
